package shiro;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import io.jsonwebtoken.*;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;

import javax.naming.event.ObjectChangeListener;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;

/**
 * @author lzh
 * @description 简单工厂模式，用于提供生成token和验证token的辅助函数
 * @date 2021/2/7
 */
public class JwtUtil {
    private static String privateKey = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9";
    private static long tokenDuration = 24 * 60;// token的有效时间， 以分钟为单位

    public static void setPrivateKey(String newKey) {
        privateKey = newKey;
    }

    /**
     * 设置token的有效时长，以分钟为单位
     * @param duration
     */
    public static void setTokenDuration(long duration) {
        tokenDuration = duration;
    }

    /**
     * 产生token
     *
     * @param user
     * @return
     */
    public static String genToken(CurrentUser user) {
        LocalDateTime dateTime = LocalDateTime.now();
        Date issuedAt = Date.from(dateTime.atZone(ZoneId.of("Asia/Shanghai")).toInstant());
//        Date expiration = Date.from(dateTime.plus(1, ChronoUnit.SECONDS).atZone(ZoneId.of("Asia/Shanghai")).toInstant());// 1秒后过期
        Date expiration = Date.from(dateTime.plus(tokenDuration, ChronoUnit.MINUTES).atZone(ZoneId.of("Asia/Shanghai")).toInstant());
        String res = Jwts.builder()
                .claim("user", user)
                .setIssuedAt(issuedAt)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, privateKey)
                .compact();
        return res;
    }


    /**
     * 从token中获取信息, 如果返回空，说明token签名错误或者已过期
     *
     * @param tokenString
     * @return
     */
    public static CurrentUser get(String tokenString) {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(privateKey).parseClaimsJws(tokenString).getBody();
        }catch (ExpiredJwtException e) {
            System.out.println("token已过期"+"(" + tokenString + ")");
            return null;
        } catch (Exception e) {
            System.out.println("token无效");
            return null;
        }
        Map<String, Object> map = (Map<String, Object>) claims.get("user");
        String mapStr = JSONObject.toJSONString(map, SerializerFeature.SortField);
        CurrentUser ans = JSONObject.parseObject(mapStr,  CurrentUser.class);
        return ans;
    }

}
